package com.yangyanhu.ssmc.controller;

import com.yangyanhu.ssmc.service.UserService;
import com.yangyanhu.ssmc.shiro.pojo.User;
import com.yangyanhu.ssmc.shiro.utils.AesCipherUtil;
import com.yangyanhu.ssmc.shiro.utils.Constant;
import com.yangyanhu.ssmc.shiro.utils.JedisUtil;
import com.yangyanhu.ssmc.shiro.utils.JwtUtil;
import entity.Result;
import exception.CustomUnauthorizedException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * Created by yyh on 2019/2/19.
 */
@RestController
@CrossOrigin
@PropertySource("classpath:config.properties")
@RefreshScope
public class LoginController {

    @Autowired
    private UserService userService;

    /**
     * RefreshToken过期时间
     */
    @Value("${refreshTokenExpireTime}")
    private String refreshTokenExpireTime;
    @Value("${ip}")
    private String ip;


    /**
     * 登录授权
     *
     * @param user
     * @return com.springcloud.model.common.ResponseBean
     * @author Wang926454
     * @date 2018/8/30 16:21
     */
    @PostMapping("/login")
    public Result login(@RequestBody User user, HttpServletResponse httpServletResponse) {
        // 查询数据库中的帐号信息
        User userTemp = new User();
        userTemp.setAccount(user.getAccount());
        userTemp = userService.selectOne(userTemp);
        if (userTemp == null) {
            throw new CustomUnauthorizedException("该帐号不存在(The account does not exist.)");
        }
        // 密码进行AES解密
        String key = AesCipherUtil.deCrypto(userTemp.getPassword());
        // 因为密码加密是以帐号+密码的形式进行加密的，所以解密后的对比是帐号+密码
        if (key.equals(user.getAccount() + user.getPassword())) {
            // 清除可能存在的Shiro权限信息缓存
            if (JedisUtil.exists(Constant.PREFIX_SHIRO_CACHE + user.getAccount())) {
                JedisUtil.delKey(Constant.PREFIX_SHIRO_CACHE + user.getAccount());
            }
            // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
            String currentTimeMillis = String.valueOf(System.currentTimeMillis());
            JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN + user.getAccount(), currentTimeMillis, Integer.parseInt(refreshTokenExpireTime));
            // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
            String token = JwtUtil.sign(user.getAccount(), currentTimeMillis);
            httpServletResponse.setHeader("Authorization", token);
            System.out.println(token);
            httpServletResponse.setHeader("Access-Control-Expose-Headers", "Authorization");
            return Result.ok("登录成功(Login Success.)");
        } else {
            throw new CustomUnauthorizedException("帐号或密码错误(Account or Password Error.)");
        }
    }

    @DeleteMapping("/logout")
    @RequiresAuthentication
    public Result logout(){
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        // 解密获得account，用于和数据库进行对比
        String account = JwtUtil.getClaim(token, Constant.ACCOUNT);
        JedisUtil.delKey(Constant.PREFIX_SHIRO_REFRESH_TOKEN + account);
        return Result.ok("退出成功(logout Success)");
    }

    /**
     * 测试登录
     *
     * @param
     * @return com.springcloud.model.common.ResponseBean
     * @author Wang926454
     * @date 2018/8/30 16:18
     */
    @GetMapping("/article")
    public Result article() {
        Subject subject = SecurityUtils.getSubject();
        // 登录了返回true
        if (subject.isAuthenticated()) {
            String token
             = (String)subject.getPrincipal();
            // 解密获得account，用于和数据库进行对比
            String account = JwtUtil.getClaim(token, Constant.ACCOUNT);
            System.out.println(account);
            System.out.println("ip是："+ip);
            return Result.ok("您已经登录了(You are already logged in)");
        } else {
            return Result.ok("你是游客(You are guest)");
        }
    }
}
